import cn.hutool.core.lang.Console;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baidu.aip.ocr.AipOcr;
import org.json.JSONObject;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

/**
 * Created By  醉美柳舞之众星捧月
 *
 * @author 宋贤坤
 * @date 2019/5/13 11:53
 */
public class Sample {

    /** 自定义常量 **/
    private static final String RET = "ret";
    private static final String GET = "GET";
    private static final String DATA = "data";
    private static final Integer TIME= 2000;
    private static final String TEMPLATE_SIGN = "templateSign";

    /** 开发者密钥(测试) **/
    private static final String APP_ID = "16209766";
    private static final String API_KEY = "aYyRirHsG8bURQiphYyQv5Zl";
    private static final String SECRET_KEY = "8RIn5xE7fgcTfpQxLl4exQd8LbMVYVE6";

    public static void main(String[] args) throws Exception {

        /** 支持 base64的图片和网络图片 **/
        List<Word> sample = sample(LocationType.BASE64, TemplateType.TEMPLATE_SIGN_HORIZONTAL_2, ImageLocationType.IMG_PATH_HORIZONTAL_3.getAddr());
        System.out.println(sample.get(3).getWord());
        Console.error(com.alibaba.fastjson.JSONObject.toJSONString(sample));
    }

    private static List<Word> sample(LocationType locationType, TemplateType templetaType, String imgPath) throws Exception {
        List<Word> onlyWords;
        HashMap<String, String> options = new HashMap(1);
        options.put(TEMPLATE_SIGN, templetaType.getTempletaId());
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        client.setSocketTimeoutInMillis(TIME);
        client.setConnectionTimeoutInMillis(TIME);
        byte[] dataByte = null;
        if (LocationType.BASE64.equals(locationType)) {
            String base64 = Utils.imageToBase64(imgPath);
            dataByte = Utils.base64ToImageBytes(base64);
        }
        if (LocationType.URL.equals(locationType)) {
            URL url = new URL(imgPath);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(GET);
            conn.setConnectTimeout(TIME);
            InputStream inStream = conn.getInputStream();
            dataByte = Utils.readInputStream(inStream);
        }
        String baiDuResult = client.custom(dataByte, templetaType.getTempletaId(), options).toString();
        JSONObject firstObject = new JSONObject(baiDuResult);
        String data = firstObject.get(DATA).toString();
        JSONObject secondObject = new JSONObject(data);
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(data);
        if (!jsonObject.containsKey(RET)) {
            return null;
        } else {
            String ret = secondObject.get(RET).toString();
            JSONArray array = JSONUtil.parseArray(ret);
            onlyWords = array.toList(Word.class);
        }
        return onlyWords;
    }
}

class Utils {

    public static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        inStream.close();
        return outStream.toByteArray();
    }

    public static byte[] base64ToImageBytes(String imgStr) throws IOException {
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes = decoder.decodeBuffer(imgStr);
        for (int i = 0; i < bytes.length; i++) {
            if (bytes[i] < 0) {
                bytes[i] += 256;
            }
        }
        return bytes;
    }

    public static String imageToBase64(String imgFile) {
        InputStream inputStream;
        byte[] data = null;
        try {
            inputStream = new FileInputStream(imgFile);
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }
}

class Word {

    /** 识图后的字段对象 **/
    private String word;
    private String word_name;

    public String getWord() {
        return word;
    }

    public String getWord_name() {
        return word_name;
    }

    public void setWord(String word) {
        this.word = word;
    }

    public void setWord_name(String word_name) {
        this.word_name = word_name;
    }
}

enum ImageLocationType {

    /** 入参图像，本地测试枚举 **/
    IMG_PATH_HORIZONTAL_1(0, "本地-营业执照-横向-1", "C:\\Users\\song\\Desktop\\business\\TEMPLATE_SIGN_HORIZONTAL_1.jpg"),
    IMG_PATH_HORIZONTAL_2(1, "本地-营业执照-横向-2", "C:\\Users\\song\\Desktop\\business\\TEMPLATE_SIGN_HORIZONTAL_2.png"),
    IMG_PATH_HORIZONTAL_3(3, "本地-营业执照-横向-3", "C:\\Users\\song\\Desktop\\business\\TEMPLATE_SIGN_HORIZONTAL_3.jpg"),

    IMG_PATH_VERTICAL_1(10, "本地-营业执照-竖向-1", "C:\\Users\\song\\Desktop\\business\\TEMPLATE_SIGN_VERTICAL_1.jpeg"),
    IMG_PATH_VERTICAL_2(11, "本地-营业执照-竖向-2", "C:\\Users\\song\\Desktop\\business\\TEMPLATE_SIGN_VERTICAL_2.jpeg"),

    IMG_PATH_URL(20, "网络-营业执照-横向-1", "https://sxk.s3.didiyunapi.com/tincerefood/business_license.jpg");

    private Integer code;
    private String desc;
    private String addr;

    ImageLocationType(Integer code, String desc, String addr) {
        this.code = code;
        this.desc = desc;
        this.addr = addr;
    }

    public String getDesc() {
        return desc;
    }

    public String getAddr() {
        return addr;
    }

    public Integer getCode() {
        return code;
    }
}

enum LocationType {

    /** 入参类型枚举 **/
    URL(0, "网络图片"),
    BASE64(1, "本地图片");
    private Integer code;
    private String desc;

    LocationType(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public Integer getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }
}

enum TemplateType {

    /** 模板枚举(测试) **/
    TEMPLATE_SIGN_HORIZONTAL_1(0, "营业执照-横向-1", "ece1398bebe69ee8a36f83c8ad66555b"),
    TEMPLATE_SIGN_HORIZONTAL_2(1, "营业执照-横向-2-副本", "fbced2351c19e72830ee929ef693974a"),

    TEMPLATE_SIGN_VERTICAL_1(10, "营业执照-竖向-1", "2d3e446eecf09d2f30db08e0dbe540d8"),
    TEMPLATE_SIGN_VERTICAL_2(11, "营业执照-竖向-2", "4fa6cadd221b52afa833cc50b724ba04");

    private Integer code;
    private String desc;
    private String templetaId;

    TemplateType(Integer code, String desc, String templetaId) {
        this.code = code;
        this.desc = desc;
        this.templetaId = templetaId;
    }

    public Integer getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }

    public String getTempletaId() {
        return templetaId;
    }
}
